/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.example.evaluation;

import org.nudt.jCloud.evaluation.Evaluation;
import org.nudt.jCloud.infrastructure.HomegeneousCluster;
import org.nudt.jCloud.infrastructure.SlotType;
import org.nudt.jCloud.jobScheduler.AFCFSScheduler;
import org.nudt.jCloud.jobScheduler.JobScheduler;
import org.nudt.jCloud.resourceManager.GeneralReservationRM;
import org.nudt.jCloud.resourceManager.GeneralShareStateRM;
import org.nudt.jCloud.resourceManager.ResManager;
import org.nudt.jCloud.resourceManager.StaticParRM;
import org.nudt.jCloud.resourceScaler.ResourceScaler;
import org.nudt.jCloud.resourceScaler.ThresholdScaler;
import org.nudt.jCloud.simulation.CloudSchedSIM;
import org.nudt.jCloud.simulation.SIMTag;
import org.nudt.jCloud.simulation.User;
import org.nudt.jCloud.simulation.UserBroker;
import org.nudt.jCloud.workload.Workload;

public class RM_Example {

	public static void main(String[] args) {
		SlotType slotType = new SlotType(1, 1000, 250, 0);
		Workload wl1 = new Workload();
		Workload wl2 = new Workload();
		ComplementWorkload.generate(wl1, wl2, slotType);
		CloudSchedSIM.init("RMExample_static");
		HomegeneousCluster homeCluster = new HomegeneousCluster(30, 1000, 4, 4000, 1000, 200000);
		StaticParRM staticParRM = new StaticParRM("StaticParRM", homeCluster);
		staticParRM.addRM(0.5);
		staticParRM.addRM(0.5);
		UserBroker userBroker1 = new UserBroker("UserBroker1", SIMTag.RM_MODE_S);
		ResourceScaler resourceScaler1 = new ThresholdScaler(2, 0.5);
		JobScheduler jobScheduler1 = new AFCFSScheduler("FCFS-Gang");
		userBroker1.init(jobScheduler1, resourceScaler1);
		User user1 = new User("user1", wl1);
		userBroker1.addUser(user1);
		
		UserBroker userBroker2 = new UserBroker("UserBroker2", SIMTag.RM_MODE_S);
		ResourceScaler resourceScaler2 = new ThresholdScaler(2, 0.5);
		JobScheduler jobScheduler2 = new AFCFSScheduler("FCFS-Gang");
		userBroker2.init(jobScheduler2, resourceScaler2);
		User user2 = new User("user2", wl2);
		userBroker2.addUser(user2);
		for(int i=0; i<staticParRM.getRMs().size(); ++i){
			CloudSchedSIM.addRM(staticParRM.getRMs().get(i));
		}
		CloudSchedSIM.addUserBroker(userBroker1);
		CloudSchedSIM.addUserBroker(userBroker2);
		CloudSchedSIM.startSimulation();
		
		
		CloudSchedSIM.reset("RMExample_reservation");
		homeCluster.reset();
		ResManager reservationRM = new GeneralReservationRM("ReservationRM", homeCluster);
		userBroker1.reset();
		userBroker1.setRM_Mode(SIMTag.RM_MODE_R);
		jobScheduler1.reset();
		resourceScaler1.reset();
		userBroker1.init(jobScheduler1, resourceScaler1);
		user1.reset();
		userBroker1.addUser(user1);
		
		userBroker2.reset();
		userBroker2.setRM_Mode(SIMTag.RM_MODE_R);
		jobScheduler2.reset();
		resourceScaler2.reset();
		userBroker2.init(jobScheduler2, resourceScaler2);
		user2.reset();
		userBroker2.addUser(user2);
		
		CloudSchedSIM.addRM(reservationRM);
		CloudSchedSIM.addUserBroker(userBroker1);
		CloudSchedSIM.addUserBroker(userBroker2);
		CloudSchedSIM.startSimulation();
		
		CloudSchedSIM.reset("RMExample_share_state");
		homeCluster.reset();
		ResManager shareStateRM = new GeneralShareStateRM("ShareStateRM", homeCluster);
		userBroker1.reset();
		userBroker1.setRM_Mode(SIMTag.RM_MODE_S);
		jobScheduler1.reset();
		resourceScaler1.reset();
		userBroker1.init(jobScheduler1, resourceScaler1);
		user1.reset();
		userBroker1.addUser(user1);
		
		userBroker2.reset();
		userBroker2.setRM_Mode(SIMTag.RM_MODE_S);
		jobScheduler2.reset();
		resourceScaler2.reset();
		userBroker2.init(jobScheduler2, resourceScaler2);
		user2.reset();
		userBroker2.addUser(user2);
		
		CloudSchedSIM.addRM(shareStateRM);
		CloudSchedSIM.addUserBroker(userBroker1);
		CloudSchedSIM.addUserBroker(userBroker2);
		CloudSchedSIM.startSimulation();
		
		Evaluation.jobSizeDistribution(wl1);
		Evaluation.jobSizeDistribution(wl2);
				
	}

}
